﻿using lopet.data.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace lopet.data
{
    public class Molecule
    {
        private LoggerRepository logger = LoggerRepository.Instance;
        public Point Point { get; set; }
        public double Size { get; set; }
        public bool Absorbed { get; set; }
        public bool Decomposed { get; set; }
        public bool IsInZone0 { get; set; }
        public Environment _env { get; set; }

        public Molecule(Environment env, Point point, double size)
        {
            _env = env;
            Size = size;
            Point = point;
        }

        public void Decompose()
        {
            Decomposed = true;

            //Console.WriteLine(moleculeNumber + " th molecule is decomposed");
        }

        public Point CalculateNextPosition(double time) // time = deltaT
        {
            if (Absorbed)
            {
                return Point;
            }

            var stdDev = CalculatePropagationStandardDeviation(_env, time);
            var gaussRand = new GaussianRandom()
            {
                Mean = 0,
                StdDev = stdDev
            };
            var r1 = gaussRand.NextDouble();
            var r2 = gaussRand.NextDouble();
            var r3 = gaussRand.NextDouble();

            var point = new Point
            {
                X = this.Point.X + r1,
                Y = this.Point.Y + r2,
                Z = this.Point.Z + r3
            };
            return point;
        }

        private double CalculatePropagationStandardDeviation(Environment env, double time)
        {
            return Math.Sqrt(2 * env.DiffusionCoefficient * time);

            if (env.MoleculeSize > this.Size + 0.1)
            {
                return Math.Sqrt(((Environment.Boltzman * env.Temperature)
                    / (3 * Math.PI * env.Viscosity * this.Size)) * time);
            }
            return Math.Sqrt(((Environment.Boltzman * env.Temperature)
                    / (2 * Math.PI * env.Viscosity * this.Size)) * time);
        }
    }
}
